﻿using CPPEI.Coolzon.Common;
using CPPEI.Update.WCF;
using CPPEI.UpdatePackageTool.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;

namespace CPPEI.UpdatePackageTool
{
    /// <summary>
    /// OperateControl.xaml 的交互逻辑
    /// </summary>
    public partial class OperateControl : UserControl
    {
        private ContentControl _tabItem;
        private Product _product;
        private UploadThread _uploadThread;
        private string _fullVersionPath;
        private string _incrementVersionPath;
        private bool _isUpdate = false;
        private VersionHelper _versionHelper;

        private string _zipedfiledname;

        /// <summary>
        /// 被升级的应用程序信息
        /// </summary>
        private AppInfo _appInfo;

        public OperateControl()
        {
            InitializeComponent();
        }

        public OperateControl(ContentControl tabItem, Product product)
        {
            _tabItem = tabItem;
            _product = product;
            InitializeComponent();

            if (CZEnvironment.Intance == null)
            {
                // 出错，未发现应用程序信息
                Logger.Error("出错，未发现应用程序{0}的信息", "更新包生成程序");
            }
            else
            {
                _uploadThread = new UploadThread(CZEnvironment.Intance.ServiceConfig.IP, CZEnvironment.Intance.ServiceConfig.Port);
                _uploadThread.Progress += _uploadThread_Progress;
                _uploadThread.Failure += _uploadThread_Failure;
                _versionHelper = new VersionHelper(CZEnvironment.Intance.ServiceConfig.IP, CZEnvironment.Intance.ServiceConfig.Port);
            }
            

            
        }

        void _uploadThread_Failure(string errorMsg, long start, int length, long totalSize)
        {
           
        }

        void _uploadThread_Progress(string fileName, long start, int length, long totalSize, double netSpeed)
        {
            this.Dispatcher.Invoke(new Action(() =>
            {
                _ctlPlanMessage.Text = "";
                _ctlProgressBar.Maximum = totalSize;
                _ctlProgressBar.Value = start;
                _ctlLblPlan.Content = ((Convert.ToDouble(start) / Convert.ToDouble(totalSize)) * 100).ToString("f0") + "%";

                if (start + length >= totalSize && !_isUpdate)
                {
                    _isUpdate = true;
                    //更新版本信息
                    if (!_versionHelper.UpdateVersion(_product.EName, _product.AppType, _product.CurrentVersion, _crlCkbNecessary.IsChecked.Value))
                    {
                        _ctlPlanMessage.Text = "更新版本信息失败,请确保本地版本大于服务端版本！";
                    }
                }
            })); 
        }

        private void _ctlBtnStartCreate_Click(object sender, RoutedEventArgs e)
        {
            _ctlStartFileInfo.Document.Blocks.Clear();

            CreateIncrementVersion();

            CreateFullVersion();
        }

        /// <summary>
        /// 生成全版本更新包
        /// </summary>
        private void CreateFullVersion()
        {
            var queryList1Only =BasicInfoControl.OriginalVersionFiles;

            if (queryList1Only == null)
            {
                return;
            }
            _ctlStartFileInfo.AppendText("以下文件在全版本文件夹中: \r\n");

            //生成对应的更新包xml
            XmlDocument xmldoc = new XmlDocument();
            XmlNode xmlnode = xmldoc.CreateXmlDeclaration("1.0", "utf-8", null);
            xmldoc.AppendChild(xmlnode);

            XmlElement RootElm = xmldoc.CreateElement("Patch");
            RootElm.SetAttribute("Version", _product.CurrentVersion);

            xmldoc.AppendChild(RootElm);

            string packPath = string.Format("Patch_{0}-{1}", "Full", _product.CurrentVersion);
            DirectoryInfo dir = new DirectoryInfo(BasicInfoControl._createFileName);
            dir.CreateSubdirectory(packPath);

            DirectoryInfo otherDir = new DirectoryInfo(BasicInfoControl._createFileName + "\\" + packPath);
            otherDir.CreateSubdirectory("Files");


            string path = BasicInfoControl._createFileName + "\\" + packPath + "\\" + "Files";


            foreach (var v in queryList1Only)
            {
                _ctlStartFileInfo.AppendText(v.FullName + "\r\n");

                XmlElement childElm = xmldoc.CreateElement("File");
                childElm.SetAttribute("Name", v.Name);

                if (BasicInfoControl._RootFolder != v.Directory.Name)
                {
                    DirectoryInfo childDir = new DirectoryInfo(path);
                    childDir.CreateSubdirectory(v.Directory.Name);
                    v.CopyTo(path + "\\" + v.Directory.Name + "\\" + v.Name, true);

                    childElm.SetAttribute("Path", string.Format(".\\\\{0}\\\\{1}", v.Directory.Name, v.Name));

                    childElm.SetAttribute("TargetPath", string.Format("{0}\\\\{1}\\\\{2}", "@App", v.Directory.Name, v.Name));
                }
                else
                {
                    v.CopyTo(path + "\\" + v.Name, true);
                    childElm.SetAttribute("Path", v.Name);

                    childElm.SetAttribute("TargetPath", string.Format("{0}\\\\{1}", "@App", v.Name));
                }


                _ctlStartFileInfo.AppendText(string.Format("复制文件:{0} 到 {1} 完毕！", v.Name, BasicInfoControl._createFileName) + "\r\n");


                RootElm.AppendChild(childElm);

            }
            string xmlName = string.Format("{0}\\{1}", BasicInfoControl._createFileName + "\\" + packPath, "Patch_Full-" + _product.CurrentVersion + ".xml");
            xmldoc.Save(xmlName);
            _ctlStartFileInfo.AppendText("生成" + xmlName + "完毕！" + "\r\n");

            if (_ctlCreateRar.IsChecked.Value)
            {
                _fullVersionPath = BasicInfoControl._createFileName + "\\" + packPath;
                CreateRar(_fullVersionPath, xmlName);
            }
        }


        /// <summary>
        /// 生成增量式更新包
        /// </summary>
        private void CreateIncrementVersion()
        {
            if (string.IsNullOrEmpty(BasicInfoControl._createFileName))
            {
                return;
            }

            if (BasicInfoControl.CurrentVersionFiles != null && BasicInfoControl.OriginalVersionFiles != null)
            {

                //A custom file comparer defined below
                FileCompare myFileCompare = new FileCompare();

                // This query determines whether the two folders contain
                // identical file lists, based on the custom file comparer
                // that is defined in the FileCompare class.
                // The query executes immediately because it returns a bool.
                bool areIdentical = BasicInfoControl.OriginalVersionFiles.SequenceEqual(BasicInfoControl.CurrentVersionFiles, myFileCompare);

                if (areIdentical == true)
                {
                    _ctlStartFileInfo.AppendText("这两个文件夹都是相同的!(文件名称和文件大小一致) \r\n");
                }
                else
                {
                    _ctlStartFileInfo.AppendText("这两个文件夹是不一样的! \r\n");
                }

                // Find the common files. It produces a sequence and doesn't 
                // execute until the foreach statement.
                var queryCommonFiles = BasicInfoControl.OriginalVersionFiles.Intersect(BasicInfoControl.CurrentVersionFiles, myFileCompare);

                if (queryCommonFiles.Count() > 0)
                {
                    _ctlStartFileInfo.AppendText("以下文件在两个文件夹中: \r\n");
                    foreach (var v in queryCommonFiles)
                    {
                        _ctlStartFileInfo.AppendText(v.FullName + "\r\n"); //shows which items end up in result list
                    }
                }
                else
                {
                    _ctlStartFileInfo.AppendText("没有共同的两个文件夹中的文件.(文件名称和文件大小不一致) \r\n");
                }

                // Find the set difference between the two folders.
                // For this example we only check one way.
                var queryList1Only = (from file in BasicInfoControl.OriginalVersionFiles
                                      select file).Except(BasicInfoControl.CurrentVersionFiles, myFileCompare);

                if (queryList1Only == null)
                {
                    return;
                }
                _ctlStartFileInfo.AppendText("以下文件在新版本文件夹中，不在源版本文件中: \r\n");

                //生成对应的更新包xml
                XmlDocument xmldoc = new XmlDocument();
                XmlNode xmlnode = xmldoc.CreateXmlDeclaration("1.0", "utf-8", null);
                xmldoc.AppendChild(xmlnode);

                XmlElement RootElm = xmldoc.CreateElement("Patch");
                RootElm.SetAttribute("Version", _product.CurrentVersion);

                xmldoc.AppendChild(RootElm);

                string packPath = string.Format("Patch_{0}-{1}", _product.PastVersion, _product.CurrentVersion);
                DirectoryInfo dir = new DirectoryInfo(BasicInfoControl._createFileName);
                dir.CreateSubdirectory(packPath);

                DirectoryInfo otherDir = new DirectoryInfo(BasicInfoControl._createFileName + "\\" + packPath);
                otherDir.CreateSubdirectory("Files");


                string path = BasicInfoControl._createFileName + "\\" + packPath + "\\" + "Files";


                foreach (var v in queryList1Only)
                {
                    _ctlStartFileInfo.AppendText(v.FullName + "\r\n");

                    XmlElement childElm = xmldoc.CreateElement("File");
                    childElm.SetAttribute("Name", v.Name);

                    if (BasicInfoControl._RootFolder != v.Directory.Name)
                    {
                        DirectoryInfo childDir = new DirectoryInfo(path);
                        childDir.CreateSubdirectory(v.Directory.Name);
                        v.CopyTo(path + "\\" + v.Directory.Name + "\\" + v.Name, true);

                        childElm.SetAttribute("Path", string.Format(".\\\\{0}\\\\{1}", v.Directory.Name, v.Name));

                        childElm.SetAttribute("TargetPath", string.Format("{0}\\\\{1}\\\\{2}", "@App", v.Directory.Name, v.Name));
                    }
                    else
                    {
                        v.CopyTo(path + "\\" + v.Name, true);
                        childElm.SetAttribute("Path", v.Name);

                        childElm.SetAttribute("TargetPath", string.Format("{0}\\\\{1}", "@App", v.Name));
                    }


                    _ctlStartFileInfo.AppendText(string.Format("复制文件:{0} 到 {1} 完毕！", v.Name,BasicInfoControl._createFileName) + "\r\n");


                    RootElm.AppendChild(childElm);

                }
                string xmlName = string.Format("{0}\\{1}", BasicInfoControl._createFileName + "\\" + packPath, "Patch_" + _product.PastVersion + "-" + _product.CurrentVersion + ".xml");
                xmldoc.Save(xmlName);
                _ctlStartFileInfo.AppendText("生成" + xmlName + "完毕！" + "\r\n");

                if (_ctlCreateRar.IsChecked.Value)
                {
                    _incrementVersionPath = BasicInfoControl._createFileName + "\\" + packPath;
                    CreateRar(_incrementVersionPath, xmlName);
                }
            }

        }

        /// <summary>
        /// 生成压缩包
        /// </summary>
        /// <param name="filePath"></param>
        private void CreateRar(string filePath,string zipedfiledname)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                return;
            }

            if (ZipUtil.Zip(filePath, filePath+".zip"))
            {
                _ctlStartFileInfo.AppendText("生成压缩包" + filePath + ".rar 完毕！" + "\r\n");
                
            }
            else
            {
                _ctlStartFileInfo.AppendText("生成压缩包" + filePath + ".rar 失败！" + "\r\n");
            }
        }

        private void _ctlBtnBack_Click(object sender, RoutedEventArgs e)
        {
            List<UserControl> uiElement;
              MainWindow.MainDictionary.TryGetValue(_product.AppType, out uiElement);
            if (uiElement != null)
            {

                _tabItem.Content = uiElement[1];
            }   
        }

        private void _ctlBtnStartUpload_Click(object sender, RoutedEventArgs e)
        {
            if (!_uploadThread._isRunning)
            {
                _isUpdate = false;
                _uploadThread.UploadIncrementalPatch(_product.EName, _product.AppType, _product.PastVersion, _product.CurrentVersion, _incrementVersionPath + ".zip");
            }
            else
            {
                MessageBox.Show("当前有更新包正在上传,请稍后再试！", "消息", MessageBoxButton.OK);
            }
          
            
        }

        private void _ctlBtnFullUplad_Click(object sender, RoutedEventArgs e)
        {
            if (!_uploadThread._isRunning)
            {
                _isUpdate = false;
                _uploadThread.UploadFullPatch(_product.EName, _product.AppType, _product.CurrentVersion, _fullVersionPath + ".zip");
            }
            else
            {
                MessageBox.Show("当前有更新包正在上传,请稍后再试！", "消息", MessageBoxButton.OK);
            }
        }

    }
}
